package com.fdb.efp.nls.service.impl.psd.repay;
import java.util.Date;

import com.fdb.efp.nls.service.facade.NlsApplyInfoService;
import com.fdb.efp.nls.service.facade.PsdSendTaxRecordService;
import com.fdb.efp.nls.service.facade.UpdateLmtPrdContService;
import com.fdb.efp.nls.service.impl.sed.repay.RepaySoltServiceImpl;
import com.fdb.efp.nls.service.vo.NlsApplyInfoVO;
import com.fdb.efp.nls.service.vo.PsdSendTaxRecordVO;
import com.fdb.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.fdb.basic.framework.core.constant.BaseConstant;
import com.fdb.basic.framework.core.constant.SDicToLocalConstant;
import com.fdb.basic.framework.core.exception.OcmSystemException;
import com.fdb.basic.framework.core.util.*;
import com.fdb.basic.framework.core.util.sdic.SDicToLocal;
import com.fdb.efp.nls.common.ConsoleConstant;
import com.fdb.efp.nls.service.facade.PubSysInfoService;
import com.fdb.efp.esb.service.bo.req.hj.ReqLoanBalanceBean;
import com.fdb.efp.esb.service.bo.req.hj.ReqLoanInfoQueryBean;
import com.fdb.efp.esb.service.bo.req.hj.ReqRepaymentDetailsInfoQueryBean;
import com.fdb.efp.esb.service.bo.resp.hj.AcctDtlInfBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespLoanBalanceQueryBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespLoanInfoQueryBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespRepaymentPlanListQueryBean;
import com.fdb.efp.esb.service.facade.hj.LoanInfoQueryService;
import com.fdb.efp.nls.common.LoanConstant;
import com.fdb.efp.nls.service.facade.AccLoanService;
import com.fdb.efp.nls.service.facade.LoanRepayDetailService;
import com.fdb.efp.nls.service.facade.LoanRepayPlanService;
import com.fdb.efp.nls.service.vo.AccLoanVO;
import com.fdb.efp.loan.service.vo.LoanRepayDetailVO;
import com.fdb.efp.loan.service.vo.LoanRepayPlanVO;
import com.fdb.efp.nls.common.constant.NlsApplyInfoEnums;
import com.fdb.efp.nls.common.constant.sed.SedNlsEnum;
import com.fdb.efp.nls.common.constant.sed.SedNlsEnum.ExceptionLocation;
import com.fdb.efp.nls.common.exception.LoanRepaySyncException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.fdb.efp.nls.common.ConsoleConstant.ACC_STATUS_4;
import static com.fdb.efp.nls.common.constant.psd.NlsReplyFlowStatus.FLOW_STATUS_6;

/**
 * 需求编号:2019D08--
 * 问题编号:
 * 开发人员: caoxin
 * 创建日期:2019/8/30
 * 功能描述:还款计划必输
 * 修改日期:2019/8/30
 * 修改描述:
 */
@Service("repaymentInfoSyncService")
public class PsdRepaymentInfoSyncServiceImpl extends RepaySoltServiceImpl {
    private static final Logger logger = LoggerFactory.getLogger(PsdRepaymentInfoSyncServiceImpl.class);

    @Override
    public void doExecute(NlsProcessBizVO nlsProcessBizVo, LoanRepayDetailVO loanRepayDetailVO) throws Exception {
        //储存系统营业日期
        Map<String, String> openDayMap = new HashMap<>();
        // 根据“还款期数”，保存对应的“是否逾期过”【1是 0否】，<期数,是否逾期过>
        Map<String, String> termIsOverDueMap = new HashMap<String, String>();

        String setlSeq = loanRepayDetailVO.getSetlSeq();
        String loanNo = loanRepayDetailVO.getLoanNo();
        RespLoanInfoQueryBean respLoanInfo = null;
        RespRepaymentPlanListQueryBean respRepayPlan = null;
        RespLoanBalanceQueryBean respLoanBalanceQueryBean = null;
        String exceptionLocation = loanRepayDetailVO.getExceptionLocation();
        logger.info("======>借据信息、还款计划信息更新插槽服务开始,流水号为:" + setlSeq + "<======");


        // 通过借据号查询借据信息，获取贷款号、发放号
        AccLoanVO accLoanVO = new AccLoanVO();
        accLoanVO.setBillNo(loanNo);
        accLoanVO = accLoanService.queryByPk(accLoanVO);
        if (Objects.isNull(accLoanVO)) {
            throw new OcmSystemException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(), "还款成功后，通过借据号【" + loanNo + "】，获取到的借据信息为空！");
        }
        String loanSeq = accLoanVO.getLoanSeq();
        String distrNo = accLoanVO.getDistrNo();

        ReqLoanInfoQueryBean reqLoanInfoQueryBean = new ReqLoanInfoQueryBean();
        ReqRepaymentDetailsInfoQueryBean reqRepaymentDetailsInfoQueryBean = new ReqRepaymentDetailsInfoQueryBean();
        ReqLoanBalanceBean reqLoanBalanceBean = new ReqLoanBalanceBean();

        String seq = Integer.toString((int)((Math.random()*9+1)*100000));
        String globalSerno = "109080"+ DateTool.getCurrentDateTimeSSS() + seq;
        logger.info("借据信息查询、还款计划明细查询查询、贷款余额查询流水：【" + globalSerno +"】");

        try {
            logger.info("前往互金查询借据信息开始---------------------");
            reqLoanInfoQueryBean.setLoanNo(loanSeq);
            reqLoanInfoQueryBean.setDistrNo(distrNo);
            respLoanInfo = loanInfoQueryService.loanInfoQuery(reqLoanInfoQueryBean, globalSerno);
            logger.info("前往互金查询借据信息结束---------------------");

            logger.info("前往互金查询还款计划明细开始---------------------");
            reqRepaymentDetailsInfoQueryBean.setAcctNo(loanSeq);
            reqRepaymentDetailsInfoQueryBean.setDistrNo(distrNo);
            respRepayPlan = loanInfoQueryService.repaymentPlanListQuery(reqRepaymentDetailsInfoQueryBean, globalSerno);
            logger.info("前往互金查询还款计划明细结束---------------------");

            logger.info("前往互金查询贷款余额开始---------------------");
            reqLoanBalanceBean.setLoanNo(loanSeq);
            reqLoanBalanceBean.setDistrNo(distrNo);
            respLoanBalanceQueryBean = loanInfoQueryService.loanBalanceQuery(reqLoanBalanceBean, globalSerno);
            logger.info("前往互金查询贷款余额结束---------------------");
        } catch (Exception e) {
            throw new LoanRepaySyncException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(), "还款成功后，同步借据、还款计划，调用互金接口异常，异常信息为：" + e.getMessage());
        }
        if (StringUtil.isNullorBank(exceptionLocation) || SedNlsEnum.ExceptionLocation.INSERT_LOAN_PLAN_AFTER_REPAY.getValue().equals(exceptionLocation)) {
            // 还款计划更新（先全删，后全插）
            this.synLoanRepayPlan(respRepayPlan, accLoanVO,openDayMap,termIsOverDueMap);
        }
        // 借据信息更新
        this.synAccLoan(accLoanVO, respLoanInfo, respLoanBalanceQueryBean,openDayMap);
        // 更新还款明细

        // 额度占用
        String applySeq = accLoanVO.getApplySeq();
        NlsApplyInfoVO nlsApplyInfoVO = new NlsApplyInfoVO();
        nlsApplyInfoVO.setApplySeq(applySeq);
        nlsApplyInfoVO = Optional.ofNullable(nlsApplyInfoService.queryByPk(nlsApplyInfoVO)).orElseGet(NlsApplyInfoVO::new);
        updateLmtPrdContService.updateLmtProdAfterRepay(nlsApplyInfoVO.getLmtApplySeq(), accLoanVO.getApplySeq(), loanRepayDetailVO.getSetlSeq());
        // 还款明细
        loanRepayDetailVO.setWfApprSts(NlsApplyInfoEnums.NlsApplyState.PASS.getKey());
        loanRepayDetailVO.setFlowStatus(FLOW_STATUS_6);
        loanRepayDetailVO.setRepayTerm("0");
        loanRepayDetailVO.setPsRemPrcp(respLoanBalanceQueryBean.getLoanBal());
        loanRepayDetailService.updateByPk(loanRepayDetailVO);
        //插入税局回写记录
        insertTaxRecord(loanRepayDetailVO);
        logger.info("======>借据信息、还款计划信息更新插槽服务结束,流水号为:" + setlSeq + "<======");

    }

    public void insertTaxRecord(LoanRepayDetailVO loanRepayDetailVO) {
        try {
            PsdSendTaxRecordVO psdSendTaxRecordVO = new PsdSendTaxRecordVO();
            psdSendTaxRecordVO.setTaxNo("");
            psdSendTaxRecordVO.setApplySeq(loanRepayDetailVO.getSetlSeq());
            psdSendTaxRecordVO.setApplyStatus("Y");
            psdSendTaxRecordVO.setApplyMsg("还款成功");
            String sendType = "3";
            if ("03".equals(loanRepayDetailVO.getSetlTyp())) {
                sendType = "4";
            }
            psdSendTaxRecordVO.setSendType(sendType);
            psdSendTaxRecordVO.setBizDate(loanRepayDetailVO.getSetlApplyDt());
            psdSendTaxRecordVO.setHandStatus("N");
            psdSendTaxRecordVO.setHandNum(0);
            psdSendTaxRecordVO.setCreateTime(new Date());
            psdSendTaxRecordService.insert(psdSendTaxRecordVO);
        } catch (Exception ex) {
            logger.error("还款成功插入回写税局表发生异常",ex);
        }
    }

    // 还款计划实时同步
    private void synLoanRepayPlan(RespRepaymentPlanListQueryBean respRepayPlan, AccLoanVO accLoanVO,Map<String,String> openDayMap,Map<String, String> termIsOverDueMap) throws LoanRepaySyncException {
        String loanNo = accLoanVO.getBillNo();
        logger.info("======>借据信息、还款计划信息更新插槽服务结束,同步还款计划信息开始,借据号为:" + loanNo + "<======");
        try {
            // 通过借据编号查询还款计划信息
            List<LoanRepayPlanVO> localLRPVoLists = loanRepayPlanService.qryAllByLoanNo(loanNo);

            // 根据“还款期数”，保存对应的“结清日期”
            Map<String, String> termClearDateMap = new HashMap<String, String>();
            Iterator<LoanRepayPlanVO> iterator = localLRPVoLists.iterator();
            while (iterator.hasNext()) {
                LoanRepayPlanVO lRepPlanVO = iterator.next();
                //根据“还款期数”，保存对应的“是否逾期过”
                termIsOverDueMap.put(lRepPlanVO.getTerm().toString(), lRepPlanVO.getIsOverDue());
                termClearDateMap.put(lRepPlanVO.getTerm().toString(), lRepPlanVO.getClearDate());
            }

            // 根据借据编号删除本地原还款计划信息
            int deleteNum = loanRepayPlanService.deleteByLoanNo(loanNo);
            if (deleteNum < 0) {
                throw new LoanRepaySyncException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(), "根据借据号【" + loanNo + "】，删除还款计划信息失败！");
            }
            String bizDate = pubSysInfoService.getOpenday(BaseConstant.SYS_ID_1001);
            List<LoanRepayPlanVO> insertLists = new ArrayList<LoanRepayPlanVO>(respRepayPlan.getAcctDtlInfArry().size());

            if (respRepayPlan.getAcctDtlInfArry().size() == 0) {
                return;
            }
            for (int i = 0; i < respRepayPlan.getAcctDtlInfArry().size(); i++) {
                AcctDtlInfBean acctDtlInfBean = respRepayPlan.getAcctDtlInfArry().get(i);
                LoanRepayPlanVO loanRepayPlan = new LoanRepayPlanVO();

                /************************************************ 借据信息同步来源于【调用互金接口返回的】 ****** start */
                loanRepayPlan.setBizDate(bizDate);
                // 借据编号  = 账户主键
                loanRepayPlan.setRefNbr(acctDtlInfBean.getAcctKwd());
                // 还款期数  = 期次
                loanRepayPlan.setTerm(Integer.parseInt(acctDtlInfBean.getRpyTime()));
                // 开始日期   = 起始日期
                loanRepayPlan.setBeginDate(DateUtility.format8To10(acctDtlInfBean.getStartDt()));
                // 到期日期  = 终止日期
                loanRepayPlan.setStmtDate(DateUtility.format8To10(acctDtlInfBean.getEndDt()));
                // 期数状态通过规则修改--这个需要测一下
                loanRepayPlan.setStatus(this.getTermStatus(acctDtlInfBean,openDayMap));
                //计划本金
                Double principal = acctDtlInfBean.getPlanPrin();
                //计划利息
                Double interest = acctDtlInfBean.getPlanInt();
                //出单罚息
                Double penaltyDue = acctDtlInfBean.getIssuePnyInt();
                //出单复利
                Double comIntDue = acctDtlInfBean.getIssueCmpdInt();

                // 应还本金  = 计划本金
                loanRepayPlan.setPrincipal(new BigDecimal(principal));
                // 已还本金  = 实还本金
                loanRepayPlan.setPrincipalPaid(new BigDecimal(acctDtlInfBean.getActRpyPrin()));
                // 应还利息 = 计划利息
                loanRepayPlan.setInterest(new BigDecimal(interest));
                // 已还利息 = 实还利息
                loanRepayPlan.setInterestPaid(new BigDecimal(acctDtlInfBean.getActRpyInt()));
                // 应还罚息 = 出单罚息
                loanRepayPlan.setPenaltyDue(new BigDecimal(penaltyDue));
                // 已还罚息 = 实还罚息
                loanRepayPlan.setPenaltyPaid(new BigDecimal(acctDtlInfBean.getActRpyPnyInt()));
                // 应还复利 = 出单复利
                loanRepayPlan.setComIntDue(new BigDecimal(comIntDue));
                // 已还复利  = 实还复利
                loanRepayPlan.setComIntPaid(new BigDecimal(acctDtlInfBean.getActRpyCmpdInt()));
                // 应还费用
                loanRepayPlan.setFeeDue(BigDecimal.ZERO);
                // 已还费用
                loanRepayPlan.setFeePaid(BigDecimal.ZERO);
                //期供 = 应还本金+应还利息+应还罚息+应还复利
                loanRepayPlan.setPerAmt(new BigDecimal(principal + interest + penaltyDue + comIntDue));
                /************************************************ 借据信息同步来源于【调用互金接口返回的】 ****** end   */

                /** ---------------- 其他字段赋值 ------------ start --------- */
                // 产品ID
                loanRepayPlan.setProductCd(accLoanVO.getPrdId());
                /**
                 *  是否逾期  1：是 ，0：否
                 *  【变更】 赋值本地表对应期数的“是否逾期过”字段值
                 *  @date 2019/07/01
                 */
                loanRepayPlan.setIsOverDue(this.getIsOverDueMethod(acctDtlInfBean.getRpyTime(), loanRepayPlan.getStatus(),termIsOverDueMap));
                // 还款计划size
                loanRepayPlan.setInitTerm(respRepayPlan.getAcctDtlInfArry().size());
                // 结清日期
                loanRepayPlan.setClearDate(this.getClearDate(acctDtlInfBean, termClearDateMap,openDayMap));
                /** ---------------- 其他字段赋值 ------------ end   --------- */

                insertLists.add(loanRepayPlan);
            }
            int num = loanRepayPlanService.batchInsert(insertLists);
            if (num < 0) {
                throw new LoanRepaySyncException(SedNlsEnum.ExceptionLocation.INSERT_LOAN_PLAN_AFTER_REPAY.getValue(), "更新还款计划失败，借据号【" + loanNo + "】");
            }
        } catch (Exception e) {
            throw new LoanRepaySyncException(e);
        } finally {
            logger.info("======>借据信息、还款计划信息更新插槽服务结束,同步还款计划信息结束,借据号为:" + loanNo + "<======");
        }
    }

    /**
     * 判断“已到期”
     * N 正常
     * O 逾期
     * P 结清
     * 到期日期<营业日期，应还=实还或未还为0，状态为P,应还!=实还或未还不为0，状态为O;
     * 到期日期=营业日期，应还=实还或未还为0，状态为P,应还!=实还或未还不为0，状态为N;
     * 到期日期>营业日期，状态为N
     */
    private String getTermStatus(AcctDtlInfBean acctDtlInfBean,Map<String,String> openDayMap) {
        String termStatus = null;
        //到期日期  = 终止日期
        String endDate = acctDtlInfBean.getEndDt();
        String sysDate = this.getSysOpenDay(openDayMap);
        //应还本金 = 计划本金
        Double principal = acctDtlInfBean.getPlanPrin();
        //实还本金
        Double principalPaid = acctDtlInfBean.getActRpyPrin();
        try {
            // 到期日期<营业日期，应还=实还或未还为0，状态为P,应还!=实还或未还不为0，状态为O
            if (TimeUtil.compareDates(DateUtility.format8To10(endDate), sysDate) == -1) {
                if (Double.doubleToLongBits(principal) == Double.doubleToLongBits(principalPaid)) {
                    termStatus = LoanConstant.REPAYPLAN_STATUE_P;
                } else {
                    termStatus = LoanConstant.REPAYPLAN_STATUE_O;
                }
            }
            // 到期日期=营业日期，应还=实还或未还为0，状态为P,应还!=实还或未还不为0，状态为N
            else if (TimeUtil.compareDates(DateUtility.format8To10(endDate), sysDate) == 0) {
                if (Double.doubleToLongBits(principal) == Double.doubleToLongBits(principalPaid)) {
                    termStatus = LoanConstant.REPAYPLAN_STATUE_P;
                } else {
                    termStatus = LoanConstant.REPAYPLAN_STATUE_N;
                }
            }
            // 到期日期>营业日期，状态为N
            else if (TimeUtil.compareDates(DateUtility.format8To10(endDate), sysDate) == 1) {
                termStatus = LoanConstant.REPAYPLAN_STATUE_N;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("还款成功后，同步还款计划时，获取期数状态出现异常，异常信息为：", e);
        }
        return termStatus;
    }

    /**
     * 获取结清日期
     * 1.当原结清日期不为空时，还是赋原结清日期；
     * 2.当原结清日期为空时，若计划本金 = 实还本金，计划利息 = 实还利息， 出单罚息 = 实还罚息， 出单复利 = 实还复利，结清日期取系统营业日期，否则为null
     */
    private String getClearDate(AcctDtlInfBean acctDtlInfBean, Map<String, String> termClearDateMap,Map<String, String> openDayMap) {
        String clearDate = null;
        if (StringUtil.isStrNotEmpty(termClearDateMap.get(acctDtlInfBean.getRpyTime()))) {
            clearDate = termClearDateMap.get(acctDtlInfBean.getRpyTime());
        } else {
            if (acctDtlInfBean.getPlanPrin() == acctDtlInfBean.getActRpyPrin() && acctDtlInfBean.getPlanInt() == acctDtlInfBean.getActRpyInt() &&
                    acctDtlInfBean.getIssuePnyInt() == acctDtlInfBean.getActRpyPnyInt() && acctDtlInfBean.getIssueCmpdInt() == acctDtlInfBean.getActRpyCmpdInt()) {
                clearDate = this.getSysOpenDay(openDayMap);
            }
        }
        return clearDate;
    }

    /**
     * 获取“是否逾期过”字段值
     */
    private String getIsOverDueMethod(String term, String termStatus,Map<String, String> termIsOverDueMap) {
        String isOverDue = SedNlsEnum.YesOrNo.NO.getValue();
        //当原“是否逾期过”字段为“是”
        if (SedNlsEnum.YesOrNo.YES.getValue().equals(termIsOverDueMap.get(term))) {
            isOverDue = termIsOverDueMap.get(term);
        }
        //当原“是否逾期过”字段为“否”，且当前期数状态为“逾期”
        if (SedNlsEnum.YesOrNo.NO.getValue().equals(termIsOverDueMap.get(term)) && LoanConstant.REPAYPLAN_STATUE_O.equals(termStatus)) {
            isOverDue = SedNlsEnum.YesOrNo.YES.getValue();
            //更新期数为term的是否逾期过字段值
            termIsOverDueMap.put(term, isOverDue);
        }
        return isOverDue;
    }


    // 借据信息实时同步
    private void synAccLoan(AccLoanVO accLoanVO, RespLoanInfoQueryBean respLoanInfoQueryBean, RespLoanBalanceQueryBean respLoanBalanceQueryBean,Map<String, String> openDayMap) throws LoanRepaySyncException {
        String loanNo = accLoanVO.getBillNo();
        logger.info("======>借据信息、还款计划信息更新插槽服务结束,同步借据信息开始,借据号为:" + loanNo + "<======");
        try {
            /************************************************ 借据信息同步来源于【调用互金接口返回的】   ********************************* start */
            // 借据余额  = 贷款余额
            accLoanVO.setLoanBalance(respLoanBalanceQueryBean.getLoanBal());
            // 应收利息累计 = 出单利息
            accLoanVO.setReceIntCumu(respLoanBalanceQueryBean.getDstrInfArry()[0].getIssueInt());
            // 实收利息累计 = 已还利息
            accLoanVO.setActualIntCumu(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydInt());
            // 欠息累计 = 应还利息
            accLoanVO.setDelayIntCumu(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpyblInt_1());
            // 应收复利累计  = 出单复利
            accLoanVO.setUnpdArrPrnBal(respLoanBalanceQueryBean.getDstrInfArry()[0].getIssueCmpdInt());
            // 实收拖欠本金的罚息    = 已还罚息
            accLoanVO.setActArrsIntBal(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydPnyInt());
            // 实收复利 = 已还复利
            accLoanVO.setActArrPrnBal(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydCmpdInt());
            // 拖欠本金的罚息（应收未收）  = 应还罚息
            accLoanVO.setUnpdArrsIntBal1(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpyblPnyInt_1());
            // 应收复利（应收未收） = 应还复利
            accLoanVO.setUnpdArrPrnBal1(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpyblCmpdInt_1());
            // 欠息累计 = 出单罚息
            accLoanVO.setDelayIntCumu1(respLoanBalanceQueryBean.getDstrInfArry()[0].getIssuePnyInt());

            String rulingIr = respLoanInfoQueryBean.getBnchmrkRate();
            // 基准利率
            accLoanVO.setRulingIr(StringUtil.isNotEmpty(rulingIr) ? new BigDecimal(rulingIr).divide(new BigDecimal("100")) : BigDecimal.ZERO);
            // 利息执行年利率  = 正常利率
            accLoanVO.setRealityIrY(null == respLoanInfoQueryBean.getComIntRate() ? BigDecimal.ZERO : respLoanInfoQueryBean.getComIntRate().divide(new BigDecimal("100")));
            // 结清日期 = 结清日期
            accLoanVO.setSettlDate(StringUtils.isEmpty(respLoanInfoQueryBean.getCldDt()) ? null : DateUtility.format8To10(respLoanInfoQueryBean.getCldDt()));
            String accSts = AccLoanStatusUtils.transferAccStatusByHj(respLoanInfoQueryBean.getAcctStDsc(), respLoanInfoQueryBean.getAcctLdgrSt());

            // 台账状态  = 账户核算状态
            accLoanVO.setAccountStatus(accSts);
            if (ConsoleConstant.ACC_STATUS_1.equals(accSts)) {
                // 正常贷款余额  = 贷款余额
                accLoanVO.setNormalBalance(respLoanBalanceQueryBean.getLoanBal());
                // 拖欠本金 = 0.00
                accLoanVO.setUnpdPrinBal(BigDecimal.ZERO);
            } else if (ConsoleConstant.ACC_STATUS_10.equals(accSts) || ConsoleConstant.ACC_STATUS_14.equals(accSts)) {
                // 拖欠本金 = 贷款余额
                accLoanVO.setUnpdPrinBal(respLoanBalanceQueryBean.getLoanBal());
                // 正常贷款余额 = 0.00
                accLoanVO.setNormalBalance(BigDecimal.ZERO);
            }
            // 宽限期 caoxin:加3天 caoxin:测试看看
            accLoanVO.setGraceDay(StringUtil.isStrNotEmpty(respLoanInfoQueryBean.getGrcDay()) ? new BigDecimal(respLoanInfoQueryBean.getGrcDay()): BigDecimal.ZERO);
            /************************************************ 借据信息同步来源于【调用互金接口返回的】   ********************************* end   */

            /******************* 借据信息同步来源于【还款计划表】************ start */
            //根据借据号获取还款计划信息
            List<LoanRepayPlanVO> loanRepayPlanVOs = loanRepayPlanService.qryAllByLoanNo(loanNo);
            if (null != loanRepayPlanVOs || loanRepayPlanVOs.size() > 0) {
                // 逾期起始日  期数最小的逾期到期日
                accLoanVO.setCapOverdueDate(this.getMinOverdueDate(loanRepayPlanVOs));
                // 当前逾期期数  还款计划中所有的期数状态为“逾期”的总数
                accLoanVO.setOverTimesCurrent(this.getOverTimesCurrent(loanRepayPlanVOs));
                // 累计逾期期数  统计“是否逾期过” 1：是 ，0：否
                accLoanVO.setOverTimesTotal(this.getOverTimesTotal(loanRepayPlanVOs));
                // 最高逾期期数  统计连续期数状态为“逾期”的最多的一次
                accLoanVO.setMaxTimesTotal(this.getMaxTimesTotal(loanRepayPlanVOs));
                // 当前期数 【起始日 < 系统日期 <= 到日期】
                accLoanVO.setCurrTerm(this.getCurTerm(loanRepayPlanVOs,openDayMap));
            }

            /******************* 借据信息同步来源于【还款计划表】************ end   */
            accLoanVO.setBizDate(getSysOpenDay(openDayMap));

            // 最后修改时间
            accLoanVO.setLastUpdateTime(TimeUtil.getCurrentDateTime());
            // 最后修改人
            accLoanVO.setLastUpdateUser(BaseConstant.ADMIN);

            int num = accLoanService.updateByPk(accLoanVO);
            if (num < 0) {
                throw new LoanRepaySyncException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(), "更新借据表信息出错------------借据号【" + accLoanVO.getBillNo() + "】");
            }
        } catch (Exception e) {
            throw new LoanRepaySyncException(e);
        } finally {
            logger.info("======>借据信息、还款计划信息更新插槽服务结束,同步借据信息结束,借据号为:" + loanNo + "<======");
        }
    }

    /**
     * 获取台账状态
     *
     * @author qiuyf
     * @version 0.1 初始为0.1,后续变更则修改
     * @since 2019年7月3日 下午9:10:18
     */
    @SuppressWarnings("unused")
    private String getAccLoanSts(String acctSts, String setledDate, BigDecimal loanBalance,Map<String, String> openDayMap) {
        String accLoanSts = ConsoleConstant.ACC_STATUS_1;
        try {
            if (StringUtil.isStrNotEmpty(setledDate)) {
                String openDay = this.getSysOpenDay(openDayMap);
                // 营业日期大于等于结清日期
                if (TimeUtil.compareDates(openDay, setledDate) > -1) {
                    accLoanSts = ACC_STATUS_4;
                }
            }
            // 贷款余额小于等于0
            if (loanBalance.compareTo(BigDecimal.ZERO) < 1) {
                accLoanSts = ACC_STATUS_4;
            }
            if (!ACC_STATUS_4.equals(accLoanSts)) {
                accLoanSts = SDicToLocal.getLocalSysDicVal(SDicToLocalConstant.ACC_STATUS, acctSts);
            }
        } catch (Exception e) {
            logger.error("还款成功更新借据信息时，获取台账状态出现异常，异常信息为：", e);
        }
        return accLoanSts;
    }

    /**
     * 逾期起始日（期数最小的逾期到期日）
     */
    private String getMinOverdueDate(List<LoanRepayPlanVO> loanRepayPlanVOs) {
        List<LoanRepayPlanVO> resultList = loanRepayPlanVOs.stream()
                //筛选期数状态为“逾期”的还款计划信息
                .filter(lrpvo -> {
                    return LoanConstant.REPAYPLAN_STATUE_O.equals(lrpvo.getStatus());
                })
                //根据期数升序排序信息
                .sorted(Comparator.comparing(LoanRepayPlanVO::getTerm)).collect(Collectors.toList());

        if (null == resultList || resultList.isEmpty()) {
            return null;
        }
        return resultList.get(0).getStmtDate();
    }

    /**
     * 当前逾期期数 （还款计划中所有的期数状态为“逾期”的总数）
     */
    private BigDecimal getOverTimesCurrent(List<LoanRepayPlanVO> loanRepayPlanVOs) {
        long result = loanRepayPlanVOs.stream()
                //筛选期数状态为“逾期”的还款计划信息
                .filter(lrpvo -> {
                    return LoanConstant.REPAYPLAN_STATUE_O.equals(lrpvo.getStatus());
                })
                .count();
        return new BigDecimal(result);
    }


    /**
     * 累计逾期期数
     */
    private BigDecimal getOverTimesTotal(List<LoanRepayPlanVO> loanRepayPlanVOs) {
        long overTimeTotal = loanRepayPlanVOs.stream()
                .map(LoanRepayPlanVO::getIsOverDue)
                .filter(val -> {
                    return SedNlsEnum.YesOrNo.YES.getValue().equals(val);
                }).
                        count();
        return new BigDecimal(overTimeTotal);
    }

    /**
     * 最高逾期期数 （统计连续期数状态为“逾期”的最多的一次）
     */
    private BigDecimal getMaxTimesTotal(List<LoanRepayPlanVO> loanRepayPlanVOs) {
        List<LoanRepayPlanVO> collect = loanRepayPlanVOs.stream().filter(i -> "1".equals(i.getIsOverDue())).sorted(Comparator.comparing(LoanRepayPlanVO::getTerm)).collect(Collectors.toList());
        if (loanRepayPlanVOs == null || loanRepayPlanVOs.isEmpty()) {
            return BigDecimal.ZERO;
        }
        int max = 1;
        int count = 1;
        for (int i = 0; i < collect.size() - 1; i++) {
            if ((loanRepayPlanVOs.get(i).getTerm() + 1) == loanRepayPlanVOs.get(i + 1).getTerm()) {
                count++;
                max = max > count ? max : count;
            } else {
                count = 0;
            }
        }
        return new BigDecimal(max);
    }

    /**
     * 获取当前期数（起始日 < 系统营业日期 <= 到日期）
     */
    private BigDecimal getCurTerm(List<LoanRepayPlanVO> loanRepayPlanVOs,Map<String, String> openDayMap) {
        String openDay = this.getSysOpenDay(openDayMap);
        List<Integer> termList = loanRepayPlanVOs.stream()
                //过滤，条件：起始日 < 系统营业日期 <= 到日期
                .filter(lrp -> {
                    return (TimeUtil.compareDate(lrp.getBeginDate(), openDay) == -1 && TimeUtil.compareDate(lrp.getStmtDate(), openDay) != -1);
                })
                //取期数
                .map(LoanRepayPlanVO::getTerm)
                //升序排序
                .sorted()
                //收集成list
                .collect(Collectors.toList());
        if (null == termList || termList.isEmpty()) {
            return BigDecimal.ZERO;
        }
        return new BigDecimal(termList.get(0));
    }


    /**
     * 获取系统营业日期
     */
    private String getSysOpenDay(Map<String, String> openDayMap) {
        if (openDayMap.containsKey(BaseConstant.SYS_ID_1001)) {
            return openDayMap.get(BaseConstant.SYS_ID_1001);
        }
        String openDayStr = pubSysInfoService.getOpenday(BaseConstant.SYS_ID_1001);
        //将查询到的营业日期保存
        openDayMap.put(BaseConstant.SYS_ID_1001, openDayStr);
        return openDayStr;
    }

    @Autowired
    @Qualifier("loanInfoQueryService")
    LoanInfoQueryService loanInfoQueryService;

    @Autowired
    @Qualifier("accLoanService")
    AccLoanService accLoanService;

    @Autowired
    @Qualifier("accLoanRepayPlanService")
    LoanRepayPlanService loanRepayPlanService;

    @Autowired
    @Qualifier("pubSysInfoService")
    private PubSysInfoService pubSysInfoService;

    @Autowired
    @Qualifier("updateLmtPrdContService")
    private UpdateLmtPrdContService updateLmtPrdContService;

    @Autowired
    @Qualifier("nlsApplyInfoService")
    private NlsApplyInfoService nlsApplyInfoService;

    @Autowired
    @Qualifier("loanRepayDetailService")
    private LoanRepayDetailService loanRepayDetailService;

    @Autowired
    private PsdSendTaxRecordService psdSendTaxRecordService;
}
